/*
 *  $Id: sysapi_link.c 50 2009-02-10 05:48:05Z hyunghwan.chung $
 *
   Copyright 2005-2009 Chung, Hyung-Hwan.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an  BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

#include <xp/bas/sysapi.h>
#include <xp/bas/locale.h>
#include <xp/bas/errno.h>

#ifdef XP_HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif

int xp_link (const xp_char_t* name1, const xp_char_t* name2)
{
#if defined(_WIN32)
	return -1;
#elif defined(XP_CHAR_IS_MCHAR)
	#ifdef SYS_link
	return syscall (SYS_link, name1, name2);
	#else
	return link (name1, name2);
	#endif
#else
	xp_mchar_t name1_mb[XP_PATH_MAX + 1];
	xp_mchar_t name2_mb[XP_PATH_MAX + 1];

	if (xp_wcstomcs_strict(name1, name1_mb, xp_countof(name1_mb)) == -1) {
		return -1;
	}

	if (xp_wcstomcs_strict(name2, name2_mb, xp_countof(name2_mb)) == -1) {
		return -1;
	}

	#ifdef SYS_link
	return syscall (SYS_link, name1_mb, name2_mb);
	#else
	return link (name1_mb, name2_mb);
	#endif
#endif
}

int xp_symlink (const xp_char_t* name1, const xp_char_t* name2)
{
#if defined(_WIN32)
	return -1;
#elif defined(XP_CHAR_IS_MCHAR)
	#ifdef SYS_symlink
	return syscall (SYS_symlink, name1, name2);
	#else
	return symlink (name1, name2);
	#endif
#else
	xp_mchar_t name1_mb[XP_PATH_MAX + 1];
	xp_mchar_t name2_mb[XP_PATH_MAX + 1];

	if (xp_wcstomcs_strict(name1, name1_mb, xp_countof(name1_mb)) == -1) {
		return -1;
	}

	if (xp_wcstomcs_strict(name2, name2_mb, xp_countof(name2_mb)) == -1) {
		return -1;
	}

	#ifdef SYS_symlink
	return syscall (SYS_symlink, name1_mb, name2_mb);
	#else
	return symlink (name1_mb, name2_mb);
	#endif
#endif
}

int xp_readlink (const xp_char_t* path, xp_char_t* buf, xp_size_t size)
{
#if defined(_WIN32)
	return -1;
#elif defined(XP_CHAR_IS_MCHAR)
	#ifdef SYS_readlink
	return syscall (SYS_readlink, path, buf, size);
	#else
	return readlink (path, buf, size);
	#endif
#else
	xp_mchar_t path_mb[XP_PATH_MAX + 1];
	xp_mchar_t buf_mb[XP_PATH_MAX + 1];

	if (xp_wcstomcs_strict (
		path, path_mb, xp_countof(path_mb)) == -1) return -1;

	#ifdef SYS_readlink
	if (syscall (SYS_readlink, path_mb, buf_mb, xp_countof(buf_mb)) == -1) return -1;
	#else
	if (readlink (path_mb, buf_mb, xp_countof(buf_mb)) == -1) return -1;
	#endif

	if (xp_mcstowcs_strict(buf_mb, buf, size) == -1) return -1;
	
	return 0;
#endif
}

